#include "PDTFunction.h"

PDTFunctionDec::PDTFunctionDec(PDTCodeGraph &CG, string &name,
		PDTListOfStatements & body, PDTVar * retVar, vector<PDTVar*> &arguments) :
	PDTNode(CG) {
	this->name = name;

	int size = arguments.size();
	argc = size;
	for (int i = 0; i < size; i++) {
		PDTNode * node = arguments[i]->getNode();
		addChild(node);
		node->addParent(this);
	}

	addChild(&body);
	body.addParent(this);

	PDTNode * retNode = retVar->getNode();
	addChild(retNode);
	retNode->addParent(this);
}


PDTNode* 
PDTFunctionDec::
clone(PDTCodeGraph& CG)
{
    PDTNode* toReturn=NULL;
    PDTListOfStatements* bodyClone = dynamic_cast<PDTListOfStatements*>(getStatements()->clone(CG));

    PDTVar* retVarClone = dynamic_cast<PDTVar*>(getReturnVar()->getNode()->clone(CG));

    vector <PDTVar*> argumentsClone;
    for (unsigned int i = 0; i<argc; i++)
    {
        PDTVar * v = getArgument(i);
        PDTNode * node = v->getNode();
        argumentsClone.push_back(dynamic_cast<PDTVar*>(node->clone(CG)));
    }
    stringstream sss;
    sss<<cloneID;
    //string nameClone = name + "!" + sss.str();
    string nameClone = name;
    cloneID++;
    toReturn = new PDTFunctionDec(CG, nameClone, *bodyClone, retVarClone, argumentsClone);
    incrementCloneID();
    untouch();
    return toReturn;
}




stringstream & 
PDTFunctionDec::
toString(stringstream & ss) const 
{
    ss << "function " << name << " ( ";
    int size = children.size();
    PDTNode * varNode = NULL;
    if (size >= 3) {
        for (int i = 0; i < size - 3; i++) {
            varNode = children[i];
            varNode->toString(ss);
            ss << ", ";
        }
        varNode = children[size - 3];
        varNode->toString(ss);
        ss << ") {" << endl;
    } else {
        ss << ") {" << endl;
    }
    // children[size - 1] is the return variable
    PDTNode * body = children[size - 2];
    body->toString(ss);
    ss << "}" << endl;
    return ss;
}
